package timbap.visualizer.api.plugin.container;

import timbap.visualizer.api.model.TimeCode;

import java.util.Date;

/**
 * The <code>AbstractKeepAliveModeController</code> provides a common base
 * implementation for mode controllers that automatically publish a
 * switch command to the next mode, if a keep alive signal
 * has expired.
 *
 * @author  Andreas Pabst
 * @see     timbap.visualizer.api.plugin.container.AbstractModeController
 * @see     timbap.visualizer.api.plugin.container.KeepAliveModeController
 */
public abstract class AbstractKeepAliveModeController extends AbstractModeController
                                                      implements KeepAliveModeController {

    private long lastKeepAliveTime = -1;

    public long getLastKeepAliveTime() {
        return lastKeepAliveTime;
    }

    public void keepAlive() {
        if (isKeepAliveAccepted()) {
            lastKeepAliveTime = new Date().getTime();
        }
    }

    public boolean isKeepAliveAccepted() {
        return isActive();
    }

    public boolean hasKeepAliveExpired() {
        long tCurrentTime = new Date().getTime();
        return (lastKeepAliveTime > 0 &&
                tCurrentTime - lastKeepAliveTime >= getKeepAliveExpirationTimeInMs());
    }

    public long getKeepAliveExpirationTimeInMs() {
        return getContext().getCfg().getModeSwitchTimeInMs();
    }

    public float getKeepAliveExpirationAsFractional() {
        long tCurrentTime = new Date().getTime();
        return ((float)(tCurrentTime - lastKeepAliveTime) / getKeepAliveExpirationTimeInMs());
    }

    @Override
    public void activate() {
        super.activate();
        keepAlive();
    }

    @Override
    public void timeCodeUpdated(TimeCode pTimeCode) {
        super.timeCodeUpdated(pTimeCode);
        if (hasKeepAliveExpired()) {
            keepAliveExpired();
        }
    }

    public void keepAliveExpired() {
        publishPluginSwitchCommand(PluginSwitchCommand.NEXT);
    }
}